home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Reference Guide / C-C++ Interactive Reference Guide.iso / c_ref / csource5 / 365_01 / amisysio.c < prev    next >
C/C++ Source or Header  |  1992-04-06  |  6KB  |  196 lines

  1. /* amisysio.c */
  2.  
  3. /*-
  4.  *    Mike Rieser                 Dale Rahn
  5.  *    2410 Happy Hollow Rd. Apt D-10        540 Vine St.
  6.  *    West Lafayette, IN 47906         West Lafayette, IN 47906
  7.  *    riesermc@mentor.cc.purdue.edu        rahn@sage.cc.purdue.edu
  8.  */
  9.  
  10. #if AZTEC_C
  11.  
  12. /*
  13.  * This file is only to supply behavior a little closer to UNIX for the Aztec
  14.  * Library functions stat() and creat().
  15.  * 
  16.  * If you don't have a decent stat() function move the above #if to the
  17.  * end of the stat() function.
  18.  *
  19.  * The creat() function is pretty Aztec specific.
  20.  */
  21.  
  22. #include "amistat.h"
  23. #include <fcntl.h>
  24. #include <string.h>
  25. #include <dos/dos.h>
  26. #include <dos/dosextens.h>
  27. #include <clib/exec_protos.h>
  28. #include <clib/dos_protos.h>
  29.  
  30. #if AZTEC_C
  31. #include <pragmas/exec_lib.h>
  32. #include <pragmas/dos_lib.h>
  33. #else
  34. #include <pragmas/exec.h>
  35. #include <pragmas/dos.h>
  36. #endif
  37.  
  38. /*-
  39.  *  struct InfoData {
  40.  *     LONG   id_NumSoftErrors;     // number of soft errors on disk
  41.  *     LONG   id_UnitNumber;        // Which unit disk is (was) mounted on
  42.  *     LONG   id_DiskState;         // See defines below
  43.  *     LONG   id_NumBlocks;         // Number of blocks on disk
  44.  *     LONG   id_NumBlocksUsed;     // Number of block in use
  45.  *     LONG   id_BytesPerBlock;
  46.  *     LONG   id_DiskType;          // Disk Type code
  47.  *     BPTR   id_VolumeNode;        // BCPL pointer to volume node
  48.  *     LONG   id_InUse;             // Flag, zero if not in use
  49.  * }; // InfoData
  50.  * returned by Info(), must be on a 4 byte boundary
  51. */
  52. /*-
  53.  *  struct FileInfoBlock {
  54.  *     LONG   fib_DiskKey;
  55.  *     LONG   fib_DirEntryType;  // Type of Directory. If < 0, then a plain file.
  56.  *                   // If > 0 a directory
  57.  *     char   fib_FileName[108]; // Null terminated. Max 30 chars used for now
  58.  *     LONG   fib_Protection;    // bit mask of protection, rwxd are 3-0.
  59.  *     LONG   fib_EntryType;
  60.  *     LONG   fib_Size;          // Number of bytes in file
  61.  *     LONG   fib_NumBlocks;     // Number of blocks in file
  62.  *     struct DateStamp fib_Date;// Date file last changed
  63.  *     char   fib_Comment[80];   // Null terminated comment associated with file
  64.  *     char   fib_Reserved[36];
  65.  *  }; // FileInfoBlock
  66.  * filled by Examin(), must be on a 4 byte boundary
  67. */
  68.  
  69. int
  70. stat(char   *path, struct stat *statbuf)
  71. {
  72.     struct FileLock *lock;
  73.     struct FileInfoBlock *pFIB;
  74.     struct InfoData *pID;
  75.     int          success = 0;
  76.  
  77.     /* Zero the stat buffer. */
  78.     memset(statbuf, '\000', sizeof(struct stat));
  79.  
  80.     /* Get Lock */
  81.     lock = (struct FileLock *) Lock((UBYTE *) path, ACCESS_READ);
  82.     if ((struct FileLock *) 0 == lock)
  83.     {                    /* Lock() fails if file is a softlink */
  84.     if (ERROR_IS_SOFT_LINK == IoErr())
  85.     {
  86.         statbuf->st_mode |= S_IFLNK;/* symbolic link */
  87.         return 0;
  88.     } else
  89.         return -1;
  90.     }
  91.     /* Allocate InfoData */
  92.     pID = (struct InfoData *) AllocMem(sizeof(struct InfoData), 0);
  93.  
  94.     if ((struct InfoData *) 0 == pID)
  95.     {
  96.     UnLock((BPTR) lock);
  97.     return -1;
  98.     }
  99.     /* Allocate FileInfoBlock */
  100.     pFIB = (struct FileInfoBlock *) AllocMem(sizeof(struct FileInfoBlock), 0);
  101.  
  102.     if ((struct FileInfoBlock *) 0 == pFIB)
  103.     {
  104.     FreeMem(pID, sizeof(struct InfoData));
  105.  
  106.     UnLock((BPTR) lock);
  107.     return -1;
  108.     }
  109.     /* Fill InfoData */
  110.     if (DOSFALSE == Info((BPTR) lock, pID))
  111.     {                    /* Not critical */
  112.     FreeMem(pID, sizeof(struct InfoData));
  113.  
  114.     pID = (struct InfoData *) 0;
  115.     }
  116.     /* Fill FileInfoBlock */
  117.     if (DOSFALSE == Examine((BPTR) lock, pFIB))
  118.     {
  119.     FreeMem(pID, sizeof(struct InfoData));
  120.     FreeMem(pFIB, sizeof(struct FileInfoBlock));
  121.  
  122.     UnLock((BPTR) lock);
  123.     return -1;
  124.     }
  125.     statbuf->st_ino = pFIB->fib_DiskKey;/* inode's number */
  126.     ++statbuf->st_nlink;
  127.  
  128.     if (pFIB->fib_DirEntryType < 0)
  129.     {                    /* plain file */
  130.     statbuf->st_mode |= S_IFREG;
  131.     } else
  132.     {                    /* >= 0 then directory */
  133.     statbuf->st_mode |= S_IFDIR;
  134.     }
  135.     if (pFIB->fib_DirEntryType == ST_SOFTLINK)
  136.     {
  137.     statbuf->st_mode |= S_IFLNK;
  138.     }
  139.     if (pFIB->fib_DirEntryType == ST_SOFTLINK
  140.     || pFIB->fib_DirEntryType == ST_LINKDIR
  141.     || pFIB->fib_DirEntryType == ST_LINKFILE)
  142.     {
  143.     ++statbuf->st_nlink;
  144.     }
  145.     statbuf->st_flags = statbuf->st_attr = pFIB->fib_Protection;
  146.  
  147.     /* mask off arwed -> rwx and shift to owner bits */
  148.     statbuf->st_mode |= ((~0 ^ pFIB->fib_Protection) & 016) << 5;
  149.  
  150.     statbuf->st_size = pFIB->fib_Size;
  151.     if (pID)
  152.     statbuf->st_blksize = pID->id_BytesPerBlock;    /* optimal blocksize for
  153.                              * I/O */
  154.     statbuf->st_blocks = pFIB->fib_NumBlocks;    /* actual number of blocks
  155.                          * allocated */
  156.     statbuf->st_atime =
  157.     statbuf->st_mtime =
  158.     statbuf->st_ctime = pFIB->fib_Date.ds_Days * 24 * 60 * 60 +
  159.     pFIB->fib_Date.ds_Minute * 60 +
  160.     pFIB->fib_Date.ds_Tick / TICKS_PER_SECOND;
  161.  
  162.     UnLock((BPTR) lock);
  163.     if (pID)
  164.     FreeMem(pID, sizeof(struct InfoData));
  165.     FreeMem(pFIB, sizeof(struct FileInfoBlock));
  166.  
  167.     return 0;
  168. }
  169.  
  170.  
  171. /*
  172.  * Aztec creat() replacement.
  173.  * 
  174.  * This one doesn't delete the file, thereby preserving the original file
  175.  * protection bits!
  176.  */
  177. int
  178. creat(const char *name, int mode)
  179. {
  180.     int          c = 0;
  181.     BPTR         fh;
  182.  
  183.     fh = Open((UBYTE *) name, MODE_READWRITE);
  184.  
  185.     if (isOldDOS())
  186.     return (_creat(name, mode));
  187.     if ((BPTR) 0 == fh)
  188.     return (_open(name, O_WRONLY | O_TRUNC | O_CREAT, mode));
  189.     SetFileSize(fh, 0, OFFSET_BEGINNING);    /* Set back to beginning */
  190.     Close(fh);                /* Truncate at the start */
  191.  
  192.     return (_open(name, O_WRONLY, mode));    /* actually get a fd */
  193. }
  194.  
  195. #endif
  196.